package com.beerandjesus.sportofkings.handicapper.strategy.brisnet.singlefile;

import com.beerandjesus.sportofkings.handicapper.factory.ProfileFactory;
import com.beerandjesus.sportofkings.handicapper.model.HorseAnalysisResult;
import com.beerandjesus.sportofkings.handicapper.model.MaidenHorseAnalysisResultImpl;
import com.beerandjesus.sportofkings.handicapper.model.RaceAnalysisResultVO;
import com.beerandjesus.sportofkings.handicapper.model.RaceAnalysisResultVOImpl;
import com.beerandjesus.sportofkings.handicapper.model.brisnet.singlefile.Horse;
import com.beerandjesus.sportofkings.handicapper.model.brisnet.singlefile.HorseRace;
import com.beerandjesus.sportofkings.handicapper.model.brisnet.singlefile.Race;
import com.beerandjesus.sportofkings.handicapper.profile.postprocessor.ProfilesPostProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import static com.beerandjesus.sportofkings.handicapper.model.ResultType.FIRST_TIME_STARTER;
import static com.beerandjesus.sportofkings.handicapper.model.ResultType.SECOND_TIME_STARTER;

@Service
public class MaidenRaceAnalysisStrategyImpl extends AbstractRaceAnalysisStrategy implements MaidenRaceAnalysisStrategy<HorseRace> {

    private final AuctionPriceStudFeeRatioResolver auctionPriceStudFeeRatioResolver = new AuctionPriceStudFeeRatioResolver();
    private final MaidenSpeedResolver maidenSpeedResolver = new MaidenSpeedResolver();
    private TrainerFirstOrSecondStarterResolver trainerStatsResolver = new TrainerFirstOrSecondStarterResolver();
    private ResultTypeResolver resultTypeResolver = new ResultTypeResolver();

    @Autowired
    private SireFirstTimeStarterPercentageResolver sirePercentageResolver;
    @Autowired
    private ProfileFactory profileFactory;
    @Autowired
    private List<ProfilesPostProcessor> postProcessors;

    public RaceAnalysisResultVO analyze(HorseRace horseRace) {
        RaceAnalysisResultVOImpl vo = new RaceAnalysisResultVOImpl();
        Race race = horseRace.getRace();
        List<Horse> horses = horseRace.getHorses();
        setCommonFields(vo, race, horses);
        List<HorseAnalysisResult> results = new ArrayList<HorseAnalysisResult>();
        for (Horse horse : horses) {
            MaidenHorseAnalysisResultImpl result = new MaidenHorseAnalysisResultImpl();
            Integer pp = getPostPosition(horse);
            result.setPostPosition(pp);
            // Horse name
            result.setName(horse.getName());
            // Fast workouts
            getFastWorkoutsResolver().resolveFastWorkouts(result, horse);
            // Morning line odds
            getMorningLineOddsResolver().resolveMorningLineOdds(result, horse);
            // # of Starts
            int numStarts = horse.getPastPerformances().size();
            result.setNumberOfStarts(String.valueOf(numStarts));
            // Result type
            resultTypeResolver.resolveTypeForMaidens(result, horse);
            // Speed figure
            maidenSpeedResolver.resolveSpeedFigures(result, horse, race);

            if (result.getResultType().equals(FIRST_TIME_STARTER)
                    || result.getResultType().equals(SECOND_TIME_STARTER)) {
                /**
                 * First or second time starters only:
                 *  - sire, trainer win percentage
                 *  - auction price/stud fee ratio
                 **/
                sirePercentageResolver.resolveSireWinPercentage(result, horse.getSireName(), race.getSurface());
                trainerStatsResolver.resolveTrainerWinPercentage(result, horse);
                auctionPriceStudFeeRatioResolver.resolveAuctionPriceStudFeeRatio(result, horse);
            }
            // Profiles
            result.setProfiles(getProfileFactory().getProfiles(horseRace, horse));

            // Key trainer statistics
            result.setKeyTrainerStatistics(getKeyTrainerStatisticsResolver().resolve(horse));

            results.add(result);
        }
        for (ProfilesPostProcessor postProcessor : getPostProcessors()) {
            postProcessor.postProcessProfiles(results);
        }

        vo.setResults(results);
        return vo;
    }

    public ProfileFactory getProfileFactory() {
        return profileFactory;
    }

    public void setProfileFactory(ProfileFactory profileFactory) {
        this.profileFactory = profileFactory;
    }

    public void setSirePercentageResolver(SireFirstTimeStarterPercentageResolver sirePercentageResolver) {
        this.sirePercentageResolver = sirePercentageResolver;
    }

    public List<ProfilesPostProcessor> getPostProcessors() {
        return postProcessors;
    }

    public void setPostProcessors(List<ProfilesPostProcessor> postProcessors) {
        this.postProcessors = postProcessors;
    }

}
